// yyyy-MM-dd hh:mm:ss.SSS 所有支持的类型
function pad(str, length = 2) {
    str += ''
    while (str.length < length) {
        str = '0' + str
    }
    return str.slice(-length)
}

const parser = {
    yyyy: (dateObj) => {
        return pad(dateObj.year, 4)
    },
    yy: (dateObj) => {
        return pad(dateObj.year)
    },
    MM: (dateObj) => {
        return pad(dateObj.month)
    },
    M: (dateObj) => {
        return dateObj.month
    },
    dd: (dateObj) => {
        return pad(dateObj.day)
    },
    d: (dateObj) => {
        return dateObj.day
    },
    hh: (dateObj) => {
        return pad(dateObj.hour)
    },
    h: (dateObj) => {
        return dateObj.hour
    },
    mm: (dateObj) => {
        return pad(dateObj.minute)
    },
    m: (dateObj) => {
        return dateObj.minute
    },
    ss: (dateObj) => {
        return pad(dateObj.second)
    },
    s: (dateObj) => {
        return dateObj.second
    },
    SSS: (dateObj) => {
        return pad(dateObj.millisecond, 3)
    },
    S: (dateObj) => {
        return dateObj.millisecond
    },
}

export function formatDate(date, format = 'yyyy/MM/dd hh:mm:ss') {
    date = date instanceof Date ? date : new Date(date)
    const dateObj = {
        year: date.getFullYear(),
        month: date.getMonth() + 1,
        day: date.getDate(),
        hour: date.getHours(),
        minute: date.getMinutes(),
        second: date.getSeconds(),
        millisecond: date.getMilliseconds()
    }
    const tokenRegExp = /yyyy|yy|MM|M|dd|d|hh|h|mm|m|ss|s|SSS|SS|S/
    let flag = true
    let result = format
    while (flag) {
        flag = false
        result = result.replace(tokenRegExp, function(matched) {
            flag = true
            return parser[matched](dateObj)
        })
    }
    return result
}

export function friendlyDate(time, {
    locale = 'zh',
    threshold = [60000, 3600000],
    format = 'yyyy/MM/dd hh:mm:ss'
}) {

    const localeText = {
        zh: {
            year: '年',
            month: '月',
            day: '天',
            hour: '小时',
            minute: '分钟',
            second: '秒',
            ago: '前',
            later: '后',
            justNow: '刚刚',
            soon: '马上',
            template: '{num}{unit}{suffix}'
        },
        en: {
            year: 'year',
            month: 'month',
            day: 'day',
            hour: 'hour',
            minute: 'minute',
            second: 'second',
            ago: 'ago',
            later: 'later',
            justNow: 'just now',
            soon: 'soon',
            template: '{num} {unit} {suffix}'
        }
    }
    const text = localeText[locale] || localeText.zh
    let date = new Date(time)
    let ms = date.getTime() - Date.now()
    let absMs = Math.abs(ms)
    if (absMs < threshold[0]) {
        return ms < 0 ? text.justNow : text.soon
    }
    if (absMs >= threshold[1]) {
        return formatDate(date, format)
    }
    let num
    let unit
    let suffix = text.later
    if (ms < 0) {
        suffix = text.ago
        ms = -ms
    }
    const seconds = Math.floor((ms) / 1000)
    const minutes = Math.floor(seconds / 60)
    const hours = Math.floor(minutes / 60)
    const days = Math.floor(hours / 24)
    const months = Math.floor(days / 30)
    const years = Math.floor(months / 12)
    switch (true) {
        case years > 0:
            num = years
            unit = text.year
            break
        case months > 0:
            num = months
            unit = text.month
            break
        case days > 0:
            num = days
            unit = text.day
            break
        case hours > 0:
            num = hours
            unit = text.hour
            break
        case minutes > 0:
            num = minutes
            unit = text.minute
            break
        default:
            num = seconds
            unit = text.second
            break
    }

    if (locale === 'en') {
        if (num === 1) {
            num = 'a'
        } else {
            unit += 's'
        }
    }

    return text.template.replace(/{\s*num\s*}/g, num + '').replace(/{\s*unit\s*}/g, unit).replace(/{\s*suffix\s*}/g,
        suffix)
}
